const koa = require('koa')
const static = require('koa-static')
const path = require('path')
const config = require('./config')
const routers = require('./app/routers')
const db = require('./app/dbhelper/connect')
const koaBody = require('koa-body'); //上传文件
const uuid = require('uuid');
// 引入https 以及 koa-ssl
const https = require('https')
const sslify = require('koa-sslify').default
const cors = require('koa2-cors');
// const socketio = require("socket.io");
const WordAPI = require('./app/controllers/word')
const fs = require('fs')
const ws = require('ws');
const options = {
  key: fs.readFileSync('./httpskey/2716495_chunling.online.key'),
  cert: fs.readFileSync('./httpskey/2716495_chunling.online.pem'),
}
const app = new koa()
app.use(sslify())
app.use(cors())
app.use(static(path.join(__dirname, './static')))
app.use(koaBody({
  multipart: true,
  strict: false,
  formidable: {
    uploadDir: path.join(__dirname, 'static/upload/'),
    keepExtensions: true,
    maxFieldsSize: 3 * 1024 * 1024,
  }
}));

app.use(routers())
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx);
})

let undercoverWords = null
let rooms = []
let myWxContent = null
let clients = []
let userIndex = 0
const serve = app.listen(config.port, function(err) {
  if (err) {
    console.log('服务启动出错', err);
  } else {
    db.connect();
    console.log('blog-koa-server运行在' + config.port + '端口');
  }
});
// const serve = https.createServer(options, app.callback()).listen(config.port, (err) => {
//   if (err) {
//     console.log('服务启动出错', err);
//   } else {
//     db.connect();  // 数据库连接
//     console.log('guessWord-server运行在' + config.port + '端口');
//   }
// });

const wss = new ws.Server({ server: serve })
wss.on('connection', function (wxConnect) {
  let client_uuid = uuid.v4();
  clients.push({
    "id": client_uuid,
    "ws": wxConnect,
    "nickname": 'userIndex' + (userIndex++) 
  });
  console.log(client_uuid)
  myWxContent = wxConnect
  console.log('wss connection wxConnect ------ ')
  WordAPI.undercover().then(res => {
    if (res.code == 200) {
      let arr = res.data
      arr.sort(function () { return 0.5 - Math.random() }) // 打乱题库
      undercoverWords = arr
    } else {
      console.error(res.message)
    }
  })
  wxConnect.on('message', function (msg) {
    let obj = JSON.parse(msg)
    // console.log('接收来至客户端的信息', obj.event, obj.roomKey, obj.data.nickName)
    if (obj.event == 'createRoom') {
      createRoom(obj.roomKey, obj.data)
    }
    if (obj.event == 'leaveRoom') {
      leaveRoom(obj.roomKey, obj.data)
    }
    if (obj.event == 'deliverPocker') {
      deliverPocker(obj.roomKey)
    }
  })
})

// 生成从minNum到maxNum的随机数
function randomNum(minNum, maxNum) {
  switch (arguments.length) {
    case 1:
      return parseInt(Math.random() * minNum + 1, 10);
    case 2:
      return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
    default:
      return 0;
  }
}
// 生成从minNum到maxNum的随机数,但不含已有的数组
function getRandomNoRepeat(minNum, maxNum, had) {
  let i = randomNum(minNum, maxNum);
  if (had.indexOf(i) === -1) {
    return i;
  }
  return getRandomNoRepeat(minNum, maxNum, had);
}
function createRoom(roomKey, user) {
  if (rooms[roomKey]) { // 房间已存在，加入房间
    rooms[roomKey].users.push(user)
  } else { // 房间不存在，创建房间
    user['isOwner'] = true
    rooms[roomKey] = {
      users: [user],
      games: []
    }
  }
  for(let i=0;i<clients.length;i++) {
    if(clients[i].nickname == user.nickName) {
      clients[i]['roomKey']= roomKey
      break
    }
  }
  broadcastSend('intoRoom', roomKey, rooms[roomKey].users)
  console.log(user.nickName + '进入房间' + roomKey + ',当前房间人数' + rooms[roomKey].users.length)
}
function leaveRoom(roomKey, user) {
  let u = rooms[roomKey].users
  let index = -1
  for (let i = 0; i < u.length; i++) {
    if (u.nickName == user.nickName) {
      index = i
      break
    }
  }
  for(let j=0;j<clients.length;j++) {
    if(clients[j].nickname == user.nickName) {
      clients.splice(j, 1)
      break
    }
  }
  rooms[roomKey].users.splice(index, 1)
  if (rooms[roomKey].users.length == 0) {
    delete rooms[roomKey]
    broadcastSend('leaveRoom', roomKey, rooms[roomKey].users)
  } else {
    if (index == 0) {
      rooms[roomKey].users[0]['isOwner'] = true
    }
    broadcastSend('leaveRoom', roomKey, rooms[roomKey].users)
  }
  if (rooms[roomKey]) {
    console.log(user.nickName + '离开房间' + roomKey + ',当前房间人数' + rooms[roomKey].users.length)
  } else {
    console.log(user.nickName + '离开房间' + roomKey + ',当前房间人数为0，房间已被销毁')
  }
}
function deliverPocker(roomKey) { // 发牌
  // 排除已发过的牌
  let g = rooms[roomKey].games
  let current = []
  for (let i = 0; i < undercoverWords.length; i++) {
    if (g.indexOf(undercoverWords[i].title) == -1) {
      current.push(undercoverWords[i].title)
    }
  }
  // 打乱题库
  current.sort(function () { return 0.5 - Math.random() })
  if (current.length == 0) { // 牌已发完
    broadcastSend('revivePocker', roomKey, '')
  } else {
    // 随机取出牌，并记录
    let pocker = current[0]
    rooms[roomKey].games.push(pocker)
    // 决定哪个词是卧底牌
    let arr = pocker.split('，')
    let random = Math.random() // 随机数
    let wodi = arr[0] // 卧底牌
    let pingm = arr[1] // 平民牌
    if (random > 0.5) {
      wodi = arr[1]
      pingm = arr[0]
    }
    // 决定哪几个人是卧底牌
    let ul = rooms[roomKey].users.length // 当前房间参与游戏的人数
    // 3-5人则1个卧底，6-8则2个卧底，9-11人则3个卧底，12人以上4个卧底
    let wodiIndex = []
    if (ul >= 3 && ul <= 5) {
      wodiIndex.push(randomNum(0, ul - 1))
    }
    if (ul >= 6 && ul <= 8) {
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
    }
    if (ul >= 9 && ul <= 11) {
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
    }
    if (ul >= 12) {
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
      wodiIndex.push(getRandomNoRepeat(0, ul - 1, wodiIndex))
    }
    // 分发牌面
    let u = rooms[roomKey].users
    for (let i = 0; i < ul; i++) {
      if (wodiIndex.indexOf(i) != -1) {
        u[i]['pocker'] = wodi
      } else {
        u[i]['pocker'] = pingm
      }
    }
    broadcastSend('revivePocker', roomKey, u)
  }
}
/**
 * 广播所有客户端消息
 * @param  {String} type     广播方式(admin为系统消息，user为用户消息)
 * @param  {String} message  消息
 * @param  {String} nickname 用户昵称，广播方式为admin时可以不存在
 */
function broadcastSend(event, roomKey, data) {
  clients.forEach(function (v, i) {
    if (v.ws.readyState === ws.OPEN && v.roomKey == roomKey) {
      v.ws.send(JSON.stringify({
        event: event,
        roomKey: roomKey,
        data: data
      }));
    }
  })
}
/** 监听
 * createRoom 有人进入房间，接收key和user
 * leaveRoom 有人离开房间，接收key和user
 * deliverPocker 开始发牌，房间号key
 */

/** 触发
 * intoRoom[roomKey] 广播有人进入房间，发送当前房间内的users
 * leaveRoom[roomKey] 广播有人离开房间，发送当前房间内的users
 * revivePocker[roomKey] 发牌，发送随机分牌的数据
 */